﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace DifferentAnalizers
{
    using daStaticAnalyser.Analysers;
    using daStaticAnalyser;
    using daBase.Objects;
    using daBase.Analyser;
    using daSyntaxAnalyser;
    using daSyntaxAnalyser.SyntaxTree;

    /// <summary>
    /// Анализатор - количество параметров функции
    /// </summary>
    [AnalyserDefaultSettings("Количество параметров функции.", "Функция со слишком большим количеством параметров!", 40, "Слишком большое количество параметров функции снижает ее производительность. Для уменьшения числа параметров иногда помогает разбиение функции на 2 и более.")]
    public class FuncParamCountAnalyser : BaseStaticAnalyser
    {
        /// <summary>
        /// Максимально допустимое количество параметров функции
        /// </summary>
        [Category("Особые")]
        [DisplayName("Количество параметров")]
        [Description("Максимально допустимое количество параметров функции.")]
        public uint MaxParamCount { get { return (settings as FuncParamCountSettings).MaxParamCount; } set { (settings as FuncParamCountSettings).MaxParamCount = value; Change(); } }

        /// <summary>
        /// Инициализация
        /// </summary>
        protected override void Init()
        {
            if (settings == null)
                settings = new FuncParamCountSettings();
            (settings as FuncParamCountSettings).MaxParamCount = 8;
            base.Init();
        }

        /// <summary>
        /// Собственно анализ
        /// </summary>
        /// <param name="e">параметр анализа</param>
        protected override void DoAnalyse(SyntaxTreeArgs e)
        {
            if ((e.Element is InnerProcedureHeadElement) || (e.Element is ProcedureTypeElement))
            {
                List<FunctionVarDeclarationElement> vars;
                vars = (e.Element is InnerProcedureHeadElement) ? (e.Element as InnerProcedureHeadElement).Vars : vars = (e.Element as ProcedureTypeElement).Vars;
                int count = 0;
                if (vars != null)
                {
                    foreach (FunctionVarDeclarationElement declaration in vars)
                    {
                        count += declaration.Ids.Count;
                        if (count > (settings as FuncParamCountSettings).MaxParamCount)
                        {
                            AddError(e.Element.StartInfo, e.Element.ToString());
                            return;
                        }
                    }
                }
            }
        }
    }
}
